/*
 * Classe StatThree
 *                          - Obtem os dados da estatística 3 da base de dados (SQLite3 + ADO.NET) 
 * 							- Guarda esses dados numa Lista (C# Collections)
 * 							- Ordena os dados
 * 							- Escreve os resultados na consola e no ficheiro de texto respectivo
 *							- Tem como atributo o grau académico para o qual será calculada a estatística
 *
 *@Author: Fábio Miguel Vitória Carreto - 5618 - Engenharia Informática - Diurno
 *@Version: 03/07/2011
 * 
 * 
 * */


using System;
using System.Collections.Generic;
using System.Data;
using Mono.Data.SqliteClient;
using System.IO;

public class StatThree
{
	public string grau;
	
	public StatThree (string grau)
	{
		this.grau = grau;
		List<StructThree> statThree = this.getData();
		List<StructThree> statOrdenada = this.mostraListaOrdenada(statThree);
		this.showResultsConsole(statOrdenada);
		this.showResultsFile(statOrdenada);
	}
	
	//Ordena os dados por ordem crescente da contagem na lista
	public List<StructThree> mostraListaOrdenada(List<StructThree> stat)
	{
		stat.Sort(delegate(StructThree s1, StructThree s2) { return s1.count.CompareTo(s2.count); });
		
		return stat;
	}
	
	//Mostra resultados na consola
	public void showResultsConsole(List<StructThree> stat)
	{
		
		Console.WriteLine("\nResultados (Ordenados pela Contagem Crescente): \n");
		stat.ForEach(delegate(StructThree s) 
		{ 
			Console.WriteLine(String.Format("Ano = 200{0}, Número = {1}", s.year, s.count)); 
		});
		
	}
	
	//Mostra resultados no ficheiro respectivo
	public void showResultsFile(List<StructThree> stat)
	{
		
		string file = "Estatísticas/statThree.txt";
		TextWriter tw = new StreamWriter(file);
		tw.WriteLine(DateTime.Now);
		tw.WriteLine("Sistema Operativo: " + Environment.OSVersion.ToString());
		tw.WriteLine("");
		tw.WriteLine("Estatística 3 - Número de Docentes por ano com o Grau " + this.grau);
		tw.WriteLine(Environment.NewLine + "(Resultados ordenados pela contagem crescente)");
		tw.Close();
		
		stat.ForEach(delegate(StructThree s) 
		{
			File.AppendAllText(file, String.Format("Ano = 200{0}, Número = {1}, Grau = {2}" + 
			                                       Environment.NewLine, s.year, s.count, s.grau));
		});
		
		Console.WriteLine("\nOs resultados da estatística 3 foram também guardados em ficheiro de texto.");
		Console.WriteLine("Localização: " + file);
		
	}
	
	//Obtém os dados da estatística e retorna-os numa lista de objectos destinados para tal
	public List<StructThree> getData()
	{
		string connectionString = "URI=file:rebides.db,version=3";
		IDbConnection dbcon;
		dbcon = (IDbConnection) new SqliteConnection(connectionString);
		dbcon.Open();
		IDbCommand dbcmd = dbcon.CreateCommand();
		
		List<StructThree> stat = new List<StructThree>();
		IDataReader reader = null;
		
		for(int ano = 0; ano < 10 ; ano++)
		{
			
			//Obtem o codigo do grau inserido pelo utilizador
			string sqlGrau = String.Format("SELECT DISTINCT id FROM grau WHERE " +
				"designacao LIKE '{0}'", this.grau);
			 
			dbcmd.CommandText = sqlGrau;
			reader = dbcmd.ExecuteReader();
			
			string grau_id = null;
			
			while(reader.Read()) 
			{
				grau_id = reader.GetString (0);
			}
			
			//Obtem o número de docentes com esse grau
			string sqlFinal = String.Format("SELECT COUNT(DISTINCT docente_id) FROM registodocencia WHERE " +
				"ano = {0} AND grau_id = {1}", ano, int.Parse(grau_id));
			
			dbcmd.CommandText = sqlFinal;
			reader = dbcmd.ExecuteReader();
			
			while(reader.Read()) 
			{
				//Guarda os resultados numa lista de objectos StructThree
				string numero = reader.GetString (0);
				stat.Add(new StructThree(ano, numero, this.grau));
			}
		}
		
		return stat;
		
	}
	
	
}

//Objecto que servirá de base à estatística
//Tem como atributos o ano, a contagem obtida e o respectivo grau
public class StructThree
{
	public int year;
	public string count;
	public string grau;
	
	public StructThree(int year, string count, string grau)
	{
		this.year = year;
		this.count = count;
		this.grau = grau;
	}
}
